using System;
using System.Data;
using System.Threading.Tasks;
using ECommon.IO;
using ENodeMicro.Common;
using MySql.Data.MySqlClient;

namespace ENodeMicro.Denormalizers.Dapper
{
    /// <summary>
    /// 基类
    /// </summary>
    public class AbstractDenormalizer
    {
        protected async Task TryInsertRecordAsync(Func<IDbConnection, Task<long>> action)
        {
            try
            {
                using var connection = GetConnection();
                await action(connection);
            }
            catch (MySqlException ex)
            {
                if (ex.Number == 2627)  //主键冲突，忽略即可；出现这种情况，是因为同一个消息的重复处理
                {
                    return;
                }
                throw new IOException("Insert record failed.", ex);
            }
        }
        protected async Task TryUpdateRecordAsync(Func<IDbConnection, Task<int>> action)
        {
            try
            {
                using var connection = GetConnection();
                await action(connection);
            }
            catch (MySqlException ex)
            {
                throw new IOException("Update record failed.", ex);
            }
        }

        protected async Task TryRunTransactionAsync(Func<IDbConnection, IDbTransaction, Task<int>> action)
        {
            using var connection = GetConnection();
            connection.Open();
            var transaction = connection.BeginTransaction();
            try
            {
                await action(connection, transaction);
                transaction.Commit();
            }
            catch (Exception ex)
            {
                transaction.Rollback();
                throw new IOException("Transaction rollback.", ex);
            }
        }
        protected async Task TryRunTransactionAsync(Func<IDbConnection, IDbTransaction, Task<long>> action)
        {
            using var connection = GetConnection();
            connection.Open();
            var transaction = connection.BeginTransaction();
            try
            {
                await action(connection, transaction);
                transaction.Commit();
            }
            catch (Exception ex)
            {
                transaction.Rollback();
                throw new IOException("Transaction rollback.", ex);
            }
        }
        /// <summary>
        /// 获取数据库链接
        /// </summary>
        /// <returns></returns>
        private static IDbConnection GetConnection()
        {
            return new MySqlConnection(ConfigSettings.BusinessConnectionString);
        }
    }
}